package com.fwmagic.dynamic_rule.service.impl;

import com.fwmagic.dynamic_rule.bean.RuleAtomicParam;
import com.fwmagic.dynamic_rule.bean.RuleParam;
import com.fwmagic.dynamic_rule.service.UserActionCountQueryService;
import com.fwmagic.dynamic_rule.utils.ConnectionUtils;
import lombok.extern.slf4j.Slf4j;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;

/**
 * 查询用户行为次数条件查询服务，在ClickHouse中查询次数
 */
@Slf4j
public class UserActionCountQueryServiceClickHouseImpl implements UserActionCountQueryService {

    private static Connection connection;

    static {
        try {
            // 获取clickhouse的jdbc连接对象
            connection = ConnectionUtils.getClickHouseConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean queryActionCounts(String deviceId, RuleParam ruleParam) throws Exception {
        List<RuleAtomicParam> userActionCountParam = ruleParam.getUserActionCountParam();
        for (RuleAtomicParam ruleAtomicParam : userActionCountParam) {
            String sql = ruleAtomicParam.getActionCountQuerySql();
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setString(1, deviceId);
            ps.setLong(2, ruleAtomicParam.getRangeStart());
            ps.setLong(3, ruleAtomicParam.getRangeEnd());
            ResultSet rs = ps.executeQuery();
            log.info("countSql:{}", sql);
            while (rs.next()) {
                int cnt = rs.getInt(2);
                ruleAtomicParam.setRealCnt(ruleAtomicParam.getRealCnt() + cnt);
            }

            //只要有一个原子条件不满足，则直接返回最终结果false
            if (ruleAtomicParam.getRealCnt() != ruleAtomicParam.getCnt()) {
                return false;
            }
            log.debug("用户:{},查询了ClickHouse的count事件条件:{}:{},查询到的结果:{}", deviceId, ruleAtomicParam.getEventId(), ruleAtomicParam.getCnt(), ruleAtomicParam.getRealCnt());
        }
        //所有的原子条件都满足，返回true
        return true;
    }

    @Override
    public boolean queryActionCounts(String deviceId, RuleAtomicParam ruleAtomicParam) throws Exception {
        String sql = ruleAtomicParam.getActionCountQuerySql();
        long s = System.currentTimeMillis();

        PreparedStatement ps = connection.prepareStatement(sql);
        // 需要将sql中的?占位符替换成真实数值
        ps.setString(1, deviceId);
        ps.setLong(2, ruleAtomicParam.getRangeStart());
        ps.setLong(3, ruleAtomicParam.getRangeEnd());

        log.info("countSql:{}", sql);
        ResultSet rs = ps.executeQuery();

        long e = System.currentTimeMillis();
        log.info("用户:{},行为次数查询ClickHouse耗时:{} ms", deviceId, (e - s));

        while (rs.next()) {
            int cnt = rs.getInt(2);
            ruleAtomicParam.setRealCnt(ruleAtomicParam.getRealCnt() + cnt);
        }
        return ruleAtomicParam.getRealCnt() >= ruleAtomicParam.getCnt();
    }
}
